package com._54programer.demo.nio;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @author SN
 * @date 2019/11/28
 * @description Nio服务的
 */
public class NioServer {

    public static void main(String[] args) throws Exception{

        //1.创建选择器
        Selector selector = Selector.open();
        //2.创建通道并绑定端口
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(10001));
        //3.设置为非阻塞
        serverSocketChannel.configureBlocking(false);
        //4.把channel注册到选择器上, 并监听OP_ACCEPT事件
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        //5.等待客户连接
        while (true){
            //等待1秒
            int select = selector.select(5000);
            if(select == 0){
                System.out.println("无连接");
                continue;
            }
            //获取到事件了
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                //有客户端连接
                if(key.isAcceptable()){
                    System.out.println("有新连接");
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    //注册到selector上, 并监听OP_READ, 同时给socketChannel关联一个buffer
                    socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                }
                //有新消息
                if(key.isReadable()){
                    //获取channel
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    //获取key对应buffer
                    ByteBuffer byteBuffer = (ByteBuffer) key.attachment();
                    socketChannel.read(byteBuffer);
                    System.out.println(new String(byteBuffer.array()));
                }
                //手动从集合中移除当前的selectionKey, 防止重复操作
                iterator.remove();
            }
        }

    }

}
